<template>
  <el-dialog
      v-bind="$attrs"
      v-on="$listeners"
      :modal="false"
      :close-on-click-modal="false"
      :style="dragDialogTitleTop"
  >
    <template #title>
      <div class="drag-dialog-title">
        <slot name="title">点击此处拖拽</slot>
      </div>
    </template>
    <slot></slot>
    <template #footer>
      <slot name="footer">
        <el-button @click="handleCancel">取 消</el-button>
        <el-button type="primary" @click="handleConfirm">确 定</el-button>
      </slot>
    </template>
  </el-dialog>
</template>

<script>

export default {
  name: "drag-dialog",
  props: {
    top: {
      type: String,
      default: () => '15vh'
    }
  },
  data() {
    return {
      dialogVisible: false
    }
  },
  computed: {
    dragDialogTitleTop() {
      if (typeof this.$attrs.fullscreen !== 'boolean') {
        return `--DragDialogTitleTop:${this.$attrs.fullscreen === undefined ? this.top : '0'}`
      } else {
        return `--DragDialogTitleTop:${this.$attrs.fullscreen ? '0' : this.top}`
      }
    }
  },
  methods: {
    handleCancel() {
      this.$emit('cancel')
    },
    handleConfirm() {
      this.$emit('confirm')
    }
  },
  mounted() {
    const oDivs = [...document.querySelectorAll('.drag-dialog-title')] // 具有此类名的所有元素
    oDivs.forEach(oDiv => {
      const minTop = oDiv.getAttribute('drag-min-top')
      const ifMoveSizeArea = 0
      oDiv.onmousedown = e => {
        let target = oDiv
        while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
          target = target.parentElement
        }
        document.onselectstart = () => {
          return false
        }

        if (!target.getAttribute('init_x')) {
          target.setAttribute('init_x', target.offsetLeft)
          target.setAttribute('init_y', target.offsetTop)
        }

        const initX = parseInt(target.getAttribute('init_x'))
        const initY = parseInt(target.getAttribute('init_y'))

        // 鼠标按下，计算当前元素距离可视区的距离
        const disX = e.clientX - target.offsetLeft
        const disY = e.clientY - target.offsetTop
        document.onmousemove = e => {
          // 通过事件委托，计算移动的距离
          // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
          const l = e.clientX - disX
          const t = e.clientY - disY
          // 计算移动当前元素的位置，并且给该元素样式中的left和top值赋值
          target.style.left = l + 'px'
          target.style.top = (t < minTop ? minTop : t) + 'px'
          if (Math.abs(l - initX) > ifMoveSizeArea || Math.abs(t - initY) > ifMoveSizeArea) {
            target.setAttribute('dragged', '')
          } else {
            target.removeAttribute('dragged')
          }
        }
        document.onmouseup = e => {
          document.onmousemove = null
          document.onmouseup = null
          document.onselectstart = null
        }
        // return false不加的话可能导致黏连，拖到一个地方时div粘在鼠标上不下来，相当于onmouseup失效
        return false
      }
    })
  }
}
</script>

<style scoped>
.el-dialog__wrapper {
  pointer-events: none;
}

>>> .el-dialog {
  position: absolute;
  top: var(--DragDialogTitleTop);
  margin: 0 !important;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: auto;
}

>>> .el-dialog__header {
  padding: 0;
}

.drag-dialog-title {
  padding: 20px 20px 10px;
  cursor: move;
}
</style>
